#include "WMIReader.h"
#include "WHResult.h"

using namespace std;

WHResult* 
WMIReader::initConexion()
{
	WMIConnectionMng* wmiMng = new WMIConnectionMng();
	WHResult* whres = wmiMng->initCOMSecurityConfiguration();

	whres = wmiMng->createConnection(PC_LOCAL_USER,PC_LOCAL_PASSWORD,PC_NAMESPACE_REG,registryConnection);	
	whres = wmiMng->createConnection(PC_LOCAL_USER,PC_LOCAL_PASSWORD,PC_NAMESPACE, wmi_connection);	

	return whres;
}

WHResult* 
WMIReader::initConexion(wstring user, wstring pass, wstring host)
{
	WMIConnectionMng* wmiMng = new WMIConnectionMng();
	WHResult* whres = wmiMng->initCOMSecurityConfiguration();

	whres = wmiMng->createConnection(user, pass, host, PC_NAMESPACE_REG,registryConnection);	
	whres = wmiMng->createConnection(user, pass, host, PC_NAMESPACE, wmi_connection);	

	return whres;
}

WHResult* 
WMIReader::getRootDirectories(WMIResult<WDisk>& result)
{
	wstring res;
	res.append(L"SELECT * FROM Win32_LogicalDisk");

	WHResult* whres = wmi_connection.executeQuery(res.c_str());
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmi_connection.getIEnumWbemClassObject();

    result.fillVector(pEnumerator);
    //TODO: release pEnumerator->Release()?
    return whres;
}

WHResult*
WMIReader::getFiles(wstring path,WMIResult<WFileDirectory> & resultD)
{
	wstring resD;
	wstring resF;
    vector<wstring> tokens;

    wstring str(path);
	
	Utils::tokenize(str, tokens, DELIMITER);
    resultD.setParent(tokens[tokens.size()-1]);
    vector<wstring>::iterator the_iterator = tokens.begin();
    bool first = true;

    while( the_iterator != tokens.end() )
    {	
        if( first)
        {
            first = false;
            resD.append(L"SELECT * FROM Win32_Directory WHERE Path = '");
			resF.append(L"SELECT * FROM CIM_DataFile WHERE Path = '");
        }
        else
        {
            resD.append(DOUBLE_SLASH);
            resD.append(*the_iterator);
			resF.append(DOUBLE_SLASH);
            resF.append(*the_iterator);
        }
        ++the_iterator;
    }

    resD.append(FINAL_DOUBLE_SLASH);    
	resF.append(FINAL_DOUBLE_SLASH);    

	resD.append(L"AND Drive='");
	resD.append(tokens[0]);
	resD.append(QUOTE);

	resF.append(L"AND Drive='");
	resF.append(tokens[0]);
	resF.append(QUOTE);

	WHResult* whres = wmi_connection.executeQuery(resD.c_str());
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumeratorD = NULL;
	pEnumeratorD = wmi_connection.getIEnumWbemClassObject();
	resultD.fillVector(pEnumeratorD);
    
    whres = wmi_connection.executeQuery(resF.c_str());
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumeratorF = NULL;
	pEnumeratorF = wmi_connection.getIEnumWbemClassObject();

	resultD.fillVector(pEnumeratorF);
    return whres;
}


WMIResult<WProcess>* 
WMIReader::getProccesses()
{
    WHResult* whres = wmi_connection.executeQuery(L"SELECT * FROM Win32_Process");
    if( FAILED(whres->getHRESULT()))
    {
        delete whres;
        return 0;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmi_connection.getIEnumWbemClassObject();
   
    WMIResult<WProcess>* resProc = new WMIResult<WProcess>();
	resProc->fillVector(pEnumerator);

    delete whres;
	return resProc;	
}

WHResult* 
WMIReader::getProccesses(WMIResult<WProcess> &listProccesses)
{
	WHResult* whres = wmi_connection.executeQuery(L"SELECT * FROM Win32_Process");
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmi_connection.getIEnumWbemClassObject();
   
	listProccesses.fillVector(pEnumerator);
    return whres;
}

WMIResult<WShare>* 
WMIReader::getShares()
{		
    WHResult* whres = wmi_connection.executeQuery(L"SELECT * FROM Win32_Share");
    if( FAILED(whres->getHRESULT()))
    {
        delete whres;
        return 0;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmi_connection.getIEnumWbemClassObject();
   
    WMIResult<WShare>* res = new WMIResult<WShare>();
	res->fillVector(pEnumerator);

	return res;	
}

WHResult* 
WMIReader::getShares(WMIResult<WShare> &listShares)
{
	WHResult* whres = wmi_connection.executeQuery(L"SELECT * FROM Win32_Share");
    if( FAILED(whres->getHRESULT()))
    {
        return whres;
    }

	IEnumWbemClassObject* pEnumerator = NULL;
	pEnumerator = wmi_connection.getIEnumWbemClassObject();
   
	listShares.fillVector(pEnumerator);

    return whres;
}

void 
WMIReader::getRegistryChildren(wstring path, WMIResult<WRegistry>& registry)
{	
	RegistryManager man(&registryConnection);
 	WRegistry* rclass=new WRegistry();
	
	man.getRegistrys(R_LOCAL_MACHINE, path, &rclass);
	registry.setWRegistry(rclass);
}

int 
WMIReader::closeConnection()
{
	wmi_connection.close();
	registryConnection.close();

	return 0;
}

void
WMIReader::getStandardRegistryHives(WMIResult<WRegistry>& standarRegistrys)
{
	std::vector<WRegistry> res;
	RegistryManager man(&registryConnection);
	man.getStandardRegistryHives(res);

	WRegistry* rclass = new WRegistry();

	for(std::vector<WRegistry>::iterator i = res.begin(); i != res.end(); i++)
		rclass->addRegistry(&(*i));

	standarRegistrys.setWRegistry(rclass);
}
